/**
 *
 * Created by user on 2016-07-02.
 */
import * as rabbitMq from 'amqplib'
import * as http from 'http';
import * as Promise from 'promise';
import app from './serverApp'
import * as logger from 'winston';
import * as ws from 'ws';
import Database from './database/database';
import initDatabase from './database/init';
import {GameNames} from "./gameName";
import listeners from './network/listeners';
import PlayerManager from "./player/player-manager";
import config from './utils/config';
import createClient from "./utils/redis";
import * as ms from 'ms'

logger.level = config.getDefault('logger.level', 'info');

// start http.
function startHttpServer(callback) {
  const server = new http.Server(app);

  const port = config.get('http.port');
  server.listen(port, '::', () => {
    logger.info(`listening on ==== *:${port}`);
    callback();
  });
}

// start websocket.
function startWebSocketServer(callback) {
  const WebSocketServer = ws.Server;
  const port = config.get('websocket.port');
  const wss = new WebSocketServer({host: '::', port}, callback);
  wss.on('connection', listeners.onConnect);
}

const httpPromise = Promise.denodeify(startHttpServer)();

const websocketPromise = Promise.denodeify(startWebSocketServer)();

const databasePromise = Database.connect(config.get('database.url'), {
  useNewUrlParser: true,
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: ms('1s'),
  connectTimeoutMS: ms('5s')
});

const injectRabbitMq = async () => {
  const connection = await rabbitMq.connect('amqp://user:password@localhost:5672')
  PlayerManager.injectRmqConnection(connection)
}


async function resetWebSocketStatistic() {

  const redis = createClient()

  const batch = redis.BATCH()
  for (const name in GameNames) {
    batch.set(`gameCounter.${name}`, '0');
  }

  await batch.execAsync()
  await redis.quitAsync()
}

databasePromise.then(initDatabase);


Promise.all([
  databasePromise, resetWebSocketStatistic(), httpPromise, websocketPromise, injectRabbitMq()
])
  .catch((e) => {
      logger.error(e)
      process.exit(1)
    }
  );

export default app;
